                                                                     
                                                                     
                                                                     
                                             
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
class URIContext 
{
 
	    static int method_count, local_access, classMethodAccess, classFieldAccess=0;	
	 	String [ ]fields;
	    String field,methodStmnts, localAccessStmnts, classFieldsAccssStmnts, classMethodAccssStmnt =null;
	    String[]methodNames;
	    String [ ][ ]association;
	    int fieldsCount=0;	
		int methodCount=0;
		int localAccessCount=0;
		int classMethodAccessCount=0;
		int classFieldAccessCount=0;
	    String [ ]localAccesses;
	    String [ ] fieldAccesses;
	    String [ ] methodAccesses;
	    static  BufferedReader brMemberFields=null; 
	    static BufferedReader brMethodStmnt=null;
	    static BufferedReader brAccessStmnt=null;
		
		public static int countFields() throws IOException{
			int count=0;
	    FileInputStream fstreamForMemberFields;
		try 
		{
			fstreamForMemberFields = new FileInputStream("InfoFiles/MembersClass.txt");
			DataInputStream inForMemberFields = new DataInputStream(fstreamForMemberFields);
			BufferedReader brMemberFields = new BufferedReader(new InputStreamReader(inForMemberFields));
			 while ((brMemberFields.readLine()) != null)   {
			      count++;
			 }
			inForMemberFields.close();
		} catch (FileNotFoundException e) {		
			
			e.printStackTrace();
		}   
		finally{
			
			
		}
	    return count;
}	
		
public static int countMethods() throws IOException
{
	  int count=0;
	  FileInputStream fstreamForMethodStatement = new FileInputStream("InfoFiles/MethodsClass.txt");   
	  DataInputStream inForMethodStmnt = new DataInputStream(fstreamForMethodStatement);
	  BufferedReader brMethodStmnt = new BufferedReader(new InputStreamReader(inForMethodStmnt));
	  
	    String methodStmnts = brMethodStmnt.readLine();
	    
	    while (  methodStmnts!=null )   {
	    		count++;    		    
	    	    methodStmnts = brMethodStmnt.readLine();
	    }	        	  
	  
	  inForMethodStmnt.close();	  
	  method_count=count;
	  return count;
  }
  public static int countLocalAccess() throws IOException
  {
	  
	  //Count all entries in AccessLocalMembers.txt file including "Start of Method" and "End of Method" deliemeter
	  int count=0;
	  FileInputStream fstreamForAccessesStatement = new FileInputStream("InfoFiles/AccessesLocalMember.txt");   
	  DataInputStream inForAccessesStmnt = new DataInputStream(fstreamForAccessesStatement);
	  BufferedReader brAccessesStmnt = new BufferedReader(new InputStreamReader(inForAccessesStmnt));
	  
	    String accessesStmnts = brAccessesStmnt.readLine();
	    
	    while (  accessesStmnts!=null )   {
	    		count++;    		    
	    	    accessesStmnts = brAccessesStmnt.readLine();
	    }	        	  
	  
	  inForAccessesStmnt.close();	  
	  local_access=count;
	  
	  return count;
  }
  public static int countClassFieldAccess() throws IOException
  {
	  //Count all entries in AccessesAttributes.txt file including "Start of Method" and "End of Method" deliemeter
	  int count=0;
	  FileInputStream fstreamForAccessesStatement = new FileInputStream("InfoFiles/AccessesAttributes.txt");   
	  DataInputStream inForAccessesStmnt = new DataInputStream(fstreamForAccessesStatement);
	  BufferedReader brAccessesStmnt = new BufferedReader(new InputStreamReader(inForAccessesStmnt));
	  
	    String accessesStmnts = brAccessesStmnt.readLine();
	    
	    while (  accessesStmnts!=null )   {
	    		count++;    		    
	    	    accessesStmnts = brAccessesStmnt.readLine();
	    	    
	    }	        	  
	  
	  inForAccessesStmnt.close();  
	  
	  classFieldAccess=count;
	  return count;
  }
  public static int countClassMethodAccess() throws IOException
  {
	  //Count all entries in AccessesMethods.txt file including "Start of Method" and "End of Method" deliemeter
	  int count=0;
	  FileInputStream fstreamForAccessesStatement = new FileInputStream("InfoFiles/AccessesMethods.txt");   
	  DataInputStream inForAccessesStmnt = new DataInputStream(fstreamForAccessesStatement);
	  BufferedReader brAccessesStmnt = new BufferedReader(new InputStreamReader(inForAccessesStmnt));
	  
	    String accessesStmnts = brAccessesStmnt.readLine();
	    
	    while (  accessesStmnts!=null )   {
	    		count++;    		    
	    	    accessesStmnts = brAccessesStmnt.readLine();
	    }	        	  
	  
	  inForAccessesStmnt.close();	  
	  classMethodAccess=count;
	  return count;
  }
  boolean isMethodName(int index)
  {	  
	  if(index>0)
	  { 
		  return localAccesses[index-1].contains("Start of Method");
	  }
	  return false;
  }  
  public void extractInfo(String inputFileName, String outputFileName){
	  try{
		 	
		 	URIParser newParser=new URIParser();
		 	newParser.parseSingleClass(inputFileName);
		 		
		   		
			fieldsCount=countFields();	
			methodCount=countMethods();			
			localAccessCount=countLocalAccess();
			classMethodAccessCount=countClassMethodAccess();
			classFieldAccessCount=countClassFieldAccess();
			
		    FileInputStream fstreamForMemberFields = new FileInputStream("InfoFiles/MembersClass.txt");   
		    DataInputStream inForMemberFields = new DataInputStream(fstreamForMemberFields);
		    brMemberFields = new BufferedReader(new InputStreamReader(inForMemberFields));
		    
		    FileInputStream fstreamForMethodStatement = new FileInputStream("InfoFiles/MethodsClass.txt");   
		    DataInputStream inForMethodStmnt = new DataInputStream(fstreamForMethodStatement);
		    brMethodStmnt = new BufferedReader(new InputStreamReader(inForMethodStmnt));
		    
		    FileInputStream fstreamForLocalAccessStatement = new FileInputStream("InfoFiles/AccessesLocalMember.txt");   
		    DataInputStream inForLocalAccessStmnt = new DataInputStream(fstreamForLocalAccessStatement);
		    BufferedReader brLocalAccessStmnt = new BufferedReader(new InputStreamReader(inForLocalAccessStmnt));
		    
		    FileInputStream fstreamForClassFieldAccessStatement = new FileInputStream("InfoFiles/AccessesAttributes.txt");   
		    DataInputStream inForClassFieldsAccessStmnt = new DataInputStream(fstreamForClassFieldAccessStatement);
		    BufferedReader brClassFieldAccessStmnt = new BufferedReader(new InputStreamReader(inForClassFieldsAccessStmnt));
		    
		    FileInputStream fstreamForClassMethodAccessStatement = new FileInputStream("InfoFiles/AccessesMethods.txt");   
		    DataInputStream inForClassMethodsAccessStmnt = new DataInputStream(fstreamForClassMethodAccessStatement);
		    BufferedReader brClassMethodsAccessStmnt = new BufferedReader(new InputStreamReader(inForClassMethodsAccessStmnt));
		    
		    fields=new String[fieldsCount];
		    methodNames= new String[method_count];
		    localAccesses= new String[localAccessCount];
		    fieldAccesses=new String[classFieldAccess];
		    methodAccesses=new String[classMethodAccess];
		    
		    methodStmnts=null;
		    association=new String[methodCount][fieldsCount];
		    int i=0, j=0, k=0, l=0, m=0;
		    while ((field=brMemberFields.readLine()) != null)   {		    	
			  	fields[i++]=field;
			}		   
		    while ((methodStmnts=brMethodStmnt.readLine()) != null)   {    	
			  	methodNames[j++]=methodStmnts;
			}    
		    while ((localAccessStmnts=brLocalAccessStmnt.readLine()) != null)   {    	
			  	localAccesses[k++]=localAccessStmnts;			  	
			}
		    
		    while ((classFieldsAccssStmnts=brClassFieldAccessStmnt.readLine()) != null)   {    	
			  	fieldAccesses[l++]=classFieldsAccssStmnts;			  	
			}    
		   
		    while ((classMethodAccssStmnt=brClassMethodsAccessStmnt.readLine()) != null)   {    	
			  	methodAccesses[m++]=classMethodAccssStmnt;		
			  	
			}   
		    
		    
		    	initializeMatrix();	
		    	makeMatrix();
		    			   
		  
		    	inForMemberFields.close();
			    inForMethodStmnt.close();
			    inForLocalAccessStmnt.close();
			    inForClassFieldsAccessStmnt.close();
			    inForClassMethodsAccessStmnt.close();
			
			}  catch (Exception e){
		    	
				e.printStackTrace();
		    }
 
  
  
  }
public void markClassFieldAccessesInMatrix(){
	
	for(int iterMethod=0; iterMethod<method_count; iterMethod++)
	{
			
			for(int iterClassFieldAccess=0; iterClassFieldAccess<classFieldAccess; iterClassFieldAccess++)
			{			
				
				if(fieldAccesses[iterClassFieldAccess].contentEquals(methodNames[iterMethod]))
				{
					
					while(!fieldAccesses[iterClassFieldAccess].contentEquals("End of Method")&& iterClassFieldAccess<classMethodAccess)
		      		{
		      	
		      			if(fieldAccesses[iterClassFieldAccess].contentEquals("Start of Method")){
		      					while(!fieldAccesses[iterClassFieldAccess].contentEquals("End of Method") && iterClassFieldAccess< classMethodAccess){	    	      						
		      						iterClassFieldAccess++;	    	      		
		      					}	    	      					
		      			}    	      		
		      			else
		      			{
		      				
		      				for(int iterFields=0; iterFields<fieldsCount; iterFields++)
		      				{
		      				
		      					if(fieldAccesses[iterClassFieldAccess].contentEquals(fields[iterFields])){
		      						
		      						association[iterMethod][iterFields]="1";	    	      				
		      					
		      					}	
		      				}
		      				
		      				iterClassFieldAccess++;
		      			}
		      		}
					iterClassFieldAccess=classFieldAccess; // break the loop;
		  		}
					
			}
			
	}

}
public void markClassMethodAccessesInMatrix(){
	
	for(int iterMethod=0; iterMethod<method_count; iterMethod++)
	{
			
			for(int iterClassMethodAccess=0; iterClassMethodAccess<classMethodAccess; iterClassMethodAccess++)
			{			
				
				if(methodAccesses[iterClassMethodAccess].contentEquals(methodNames[iterMethod]))
				{
				
					while(!methodAccesses[iterClassMethodAccess].contentEquals("End of Method")&& iterClassMethodAccess<classMethodAccess)
		      		{
		      	
		      			if(methodAccesses[iterClassMethodAccess].contentEquals("Start of Method")){
		      					while(!methodAccesses[iterClassMethodAccess].contentEquals("End of Method") && iterClassMethodAccess< classMethodAccess){	    	      						
		      						iterClassMethodAccess++;	    	      		
		      					}	    	      					
		      			}    	      		
		      			else
		      			{
		      				
		      				for(int iterFields=0; iterFields<fieldsCount; iterFields++)
		      				{
		      				
		      					if(methodAccesses[iterClassMethodAccess].contentEquals(fields[iterFields])){
		      	
		      						association[iterMethod][iterFields]="1";	    	      				
		      					
		      					}	
		      				}
		      	
		      				iterClassMethodAccess++;
		      			}
		      		}
					iterClassMethodAccess=classMethodAccess; // break the loop;
		  		}
					
			}
			
	}
}
public void makeMatrix()
{
	markLocalMemberAccessesInMatrix();
	markClassFieldAccessesInMatrix();
	markClassMethodAccessesInMatrix();
}
private void initializeMatrix() {
	for(int iterMethod=0; iterMethod<methodCount; iterMethod++)
	{
		for(int iterField=0; iterField<fieldsCount; iterField++)
		{
			association[iterMethod][iterField]="0";
			
		}
		    		
	}
}
public void markLocalMemberAccessesInMatrix() {
	for(int x=0; x<methodCount; x++){	    	
		
	  	for(int z=0; z<localAccessCount; z++){
	  		if(localAccesses[z].contentEquals(methodNames[x]) && isMethodName(z)){
	  		    
	      		while(!localAccesses[z].contentEquals("End of Method")&& z<localAccessCount)
	      		{
	      			
	      			if(localAccesses[z].contentEquals("Start of Method")){
	      					while(!localAccesses[z].contentEquals("End of Method") && z< localAccessCount){	    	      						
	      						  z++;	    	      		
	      					}	    	      					
	      			}    	      		
	      			else
	      			{
	      				
	      				for(int iterFields=0; iterFields<fieldsCount; iterFields++)
	      				{	    	      					
	      					if(localAccesses[z].contentEquals(fields[iterFields])){
	      						
	      						association[x][iterFields]="1";	    	      				
	      					
	      					}	
	      				}
	      				z++;
	      			}
	      		}
	  		    z=localAccessCount; // break the loop;
	  		}
	  	}
				    		    		
	}
}

  

public void generateConexpInput(String inputFileName, String outputFileName)  {
try{
	  extractInfo(inputFileName, outputFileName);	
	 
	    BufferedWriter output;		
	    output = new BufferedWriter(new FileWriter(outputFileName));
	    output.write(";");
	    for(int iter=0; iter<fieldsCount; iter++)
	    {    
	    	output.write(fields[iter]);    
	    	output.write(";");
	    }
	    
	    output.newLine();
	    output.newLine();
	    for(int x=0; x<methodCount; x++)
	    {	    	
	    	output.write(methodNames[x]);
            output.write(";");
	    	for(int y=0; y<fieldsCount; y++)
	    	{    		
	    		output.write(association[x][y]);    		
	    		output.write(";");
	    	}    	
	    	output.newLine();
	    }	
	   
	   
		output.close();
  }catch (Exception e){
  	
	  e.printStackTrace();
   }
		
  

}
 
 
  public void generateGaliciaInput(String inputFileName, String outputFileName){
	try{
	   
	  		extractInfo(inputFileName, outputFileName);	
	  		BufferedWriter output;		
	 	    output = new BufferedWriter(new FileWriter(outputFileName));
	        output.write("[Relational Context]\rSingleClass\r[Binary Relation]\rSingleClass\r");
		   
	    
	    
	    //writing methods
	    
	    for(int x=0; x<methodCount; x++)
	    {
	    	output.write(methodNames[x]);
	    	 output.write(" | ");
	    }
	   
	
	    output.write("\r");
	    
	    //writing Fields
	    for(int iter=0; iter<fieldsCount; iter++)
	    {    
	    	output.write(fields[iter]);    
	    	output.write(" | ");
	    }
	    
	    
	    //writing associations
	    output.write("\r");
	    for(int x=0; x<methodCount; x++)
	    {
	   
	    	for(int y=0; y<fieldsCount; y++)
	    	{    		
	    		output.write(association[x][y]);    		
	    		output.write(" ");
	    	}    	
	    
	   
	    	output.write("\r");
	    }	
	    
	       output.write("[END Relational Context]");		
		   output.write("\r");		   
		   output.close();
	    }catch (Exception e){
	    	
	    	e.printStackTrace();
		}
	    
		
}
 

}







